package com.ydy.service.timeQuantum.impl;

import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import com.ydy.constant.SystemConstant;
import com.ydy.dto.RecordDTO;
import com.ydy.dto.TimeQuantumDTO;
import com.ydy.exception.BusinessException;
import com.ydy.exception.DataNotFoundException;
import com.ydy.exception.ValidateException;
import com.ydy.ienum.EnumShop;
import com.ydy.ienum.EnumTimeQuantum;
import com.ydy.mapper.BookRecordMapper;
import com.ydy.mapper.RestRecordMapper;
import com.ydy.mapper.ShopMapper;
import com.ydy.mapper.TimeQuantumMapper;
import com.ydy.model.BookRecord;
import com.ydy.model.RestRecord;
import com.ydy.model.Shop;
import com.ydy.model.Staff;
import com.ydy.model.TimeQuantum;
import com.ydy.service.timeQuantum.TimeQuantumService;
import com.ydy.utils.DateUtil;
import com.ydy.utils.ValidateUtil;
import com.ydy.vo.DateVo;
import com.ydy.vo.TimeQuantumVo;
import com.ydy.vo.other.BaseVo;
import com.ydy.vo.other.ResultVo;

import tk.mybatis.mapper.entity.Example;

@Service
@Transactional
public class TimeQuantumServiceImpl implements TimeQuantumService {

	private final static Logger log = LoggerFactory.getLogger(TimeQuantumServiceImpl.class);
	@Autowired
	private TimeQuantumMapper timeQuantumMapper;
	@Autowired
	private ShopMapper shopMapper;
	@Autowired
	private BookRecordMapper bookRecordMapper;
	@Autowired
	private RestRecordMapper restRecordMapper;

	@Override
	public List<DateVo> listDate(Long shopId) {
		Shop shop = shopMapper.selectByPrimaryKey(shopId);
		if (shop == null) {
			throw new DataNotFoundException(EnumShop.DATA_NOT_FOUND);
		}
		if (!SystemConstant.USE_STATUS_ON.equals(shop.getOnStatus())) {
			throw new BusinessException(EnumShop.SHOP_CAN_NOT_USE);
		}
		Integer bookLimit = timeQuantumMapper.selectMaxBookOneDay(shopId);
		if (bookLimit == null) {// 有可能bookLimit为空
			bookLimit = 0;
		}
		List<DateVo> list = new LinkedList<DateVo>();
		DateVo vo = null;
		Integer days = shop.getCanBookDay();
		Calendar calendar = Calendar.getInstance();
		Long now = System.currentTimeMillis();
		Date date = null;
		Date start = new Date(now);
		Date end = new Date(now + (days * DateUtil.ONE_DAY_MILLONS));
		Example example = new Example(BookRecord.class);
		Example.Criteria criteria = example.createCriteria();
		criteria.andEqualTo("shopId", shopId);
		criteria.andLessThan("bookDate", end);
		criteria.andGreaterThan("bookDate", start);
		List<BookRecord> recordList = bookRecordMapper.selectByExample(example);

		Map<String, Integer> map = null;
		if (!CollectionUtils.isEmpty(recordList)) {
			map = new HashMap<String, Integer>();
			for (BookRecord r : recordList) {
				map.put(DateUtil.getDateFile(r.getBookDate()), r.getTotal());
			}
		}

		Example restExample = new Example(RestRecord.class);
		Example.Criteria restCriteria = restExample.createCriteria();
		restCriteria.andEqualTo("shopId", shopId);
		restCriteria.andLessThan("restDate", end);
		restCriteria.andGreaterThan("restDate", start);
		List<RestRecord> restList = restRecordMapper.selectByExample(restExample);

		Map<String, String> restMap = null;
		if (!CollectionUtils.isEmpty(restList)) {
			restMap = new HashMap<String, String>();
			for (RestRecord r : restList) {
				restMap.put(DateUtil.getDateFile(r.getRestDate()), r.getRemark());
			}
		}
		String key = "";
		for (int i = 0; i <= days; i++) {
			vo = new DateVo();
			date = new Date(now + (i * DateUtil.ONE_DAY_MILLONS));
			calendar.setTime(date);
			vo.setYear(calendar.get(Calendar.YEAR));
			vo.setMonth(calendar.get(Calendar.MONTH) + 1);
			vo.setDay(calendar.get(Calendar.DAY_OF_MONTH));
			vo.setTime(date.getTime());
			vo.setBookLimit(bookLimit);
			key = DateUtil.getDateFile(date);
			if (map != null && map.containsKey(key)) {
				vo.setTotal(map.get(key));
			} else {
				vo.setTotal(0);
			}
			vo.setFull(vo.getTotal() >= vo.getBookLimit());
			if (restMap != null && restMap.containsKey(key)) {
				vo.setRest(true);
				vo.setRestRemark(restMap.get(key));
			} else {
				vo.setRest(false);
			}
			list.add(vo);
		}
		return list;
	}

	@Override
	public DateVo list(Long shopId, Date date) {
		Shop shop = shopMapper.selectByPrimaryKey(shopId);
		if (shop == null) {
			throw new DataNotFoundException(EnumShop.DATA_NOT_FOUND);
		}
		if (!SystemConstant.USE_STATUS_ON.equals(shop.getOnStatus())) {
			throw new BusinessException(EnumShop.SHOP_CAN_NOT_USE);
		}
		TimeQuantum timeQuantum = new TimeQuantum();
		timeQuantum.setShopId(shopId);
		Integer maxBook = 0;
		PageHelper.orderBy("start_time_hour asc,start_time_minute asc");
		List<TimeQuantum> list = timeQuantumMapper.select(timeQuantum);
		TimeQuantumVo vo = null;
		PageHelper.startPage(1, 1, false);
		Example example = new Example(BookRecord.class);
		Example.Criteria criteria = example.createCriteria();
		criteria.andEqualTo("shopId", shopId);
		criteria.andEqualTo("bookDate", date);
		BookRecord record = bookRecordMapper.selectOneByExample(example);
		Map<Long, Integer> map = null;
		if (record != null) {
			RecordDTO recordDTO = JSONObject.parseObject(record.getRecord(), RecordDTO.class);
			if (recordDTO != null && !CollectionUtils.isEmpty(recordDTO.getList())) {
				map = new HashMap<Long, Integer>();
				for (TimeQuantumDTO dto : recordDTO.getList()) {
					map.put(dto.getId(), dto.getTotal());
				}
			}
		}
		List<TimeQuantumVo> voList = new LinkedList<TimeQuantumVo>();
		if (!CollectionUtils.isEmpty(list)) {
			for (TimeQuantum time : list) {
				vo = new TimeQuantumVo();
				maxBook += time.getMaxBook();
				vo.setTimeQuantumId(time.getId());
				vo.setName(time.toTimeString());
				vo.setMaxBook(time.getMaxBook());
				if (map != null && map.containsKey(time.getId())) {
					vo.setTotal(map.get(time.getId()));
				} else {
					vo.setTotal(0);
				}
				vo.setFull(vo.getTotal() >= vo.getMaxBook());
				voList.add(vo);
			}
		}
		DateVo dateVo = new DateVo();
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		dateVo.setList(voList);
		dateVo.setYear(calendar.get(Calendar.YEAR));
		dateVo.setMonth(calendar.get(Calendar.MONTH) + 1);
		dateVo.setDay(calendar.get(Calendar.DAY_OF_MONTH));
		dateVo.setTime(date.getTime());
		if (record != null) {
			dateVo.setTotal(record.getTotal());
		} else {
			dateVo.setTotal(0);
		}
		dateVo.setBookLimit(maxBook);
		dateVo.setFull(dateVo.getTotal() >= dateVo.getBookLimit());
		return dateVo;
	}

	@Override
	public List<TimeQuantum> select(Long shopId) {
		Shop shop = shopMapper.selectByPrimaryKey(shopId);
		if (shop == null) {
			throw new DataNotFoundException(EnumShop.DATA_NOT_FOUND);
		}
		if (!SystemConstant.USE_STATUS_ON.equals(shop.getOnStatus())) {
			throw new BusinessException(EnumShop.SHOP_CAN_NOT_USE);
		}
		TimeQuantum timeQuantum = new TimeQuantum();
		timeQuantum.setShopId(shopId);
		PageHelper.orderBy("start_time_hour asc,start_time_minute asc");
		List<TimeQuantum> list = timeQuantumMapper.select(timeQuantum);
		return list;
	}

	@Override
	public TimeQuantum saveOrUpdate(TimeQuantum timeQuantum, Staff staff) {
		if (timeQuantum == null) {
			throw new NullPointerException();
		}
		timeQuantum.setShopId(staff.getShopId());
		// 校验数据有效
		Map<String, String> validateInfo = ValidateUtil.validateEntity(timeQuantum);
		if (!validateInfo.isEmpty()) {
			throw new ValidateException(validateInfo);
		}
		// 新增信息
		if (timeQuantum.getId() == null) {
			timeQuantumMapper.insertSelective(timeQuantum);
			log.info("新增timeQuantum成功：" + timeQuantum.getId());
		} else {// 根据id更新信息
			TimeQuantum temp = timeQuantumMapper.selectByPrimaryKey(timeQuantum.getId());
			if (temp == null) {
				log.info("找不到timeQuantum信息：" + timeQuantum.getId());
				throw new DataNotFoundException(EnumTimeQuantum.DATA_NOT_FOUND);
			}
			if (!temp.getShopId().equals(staff.getShopId())) {
				throw new BusinessException(EnumTimeQuantum.NOT_FIT_SHOP);
			}
			timeQuantumMapper.updateByPrimaryKeySelective(timeQuantum);
			log.info("更新timeQuantum成功：" + timeQuantum.getId());
		}
		return timeQuantum;
	}

	@Override
	public BaseVo delete(Long id, Staff staff) {
		if (id == null) {
			throw new NullPointerException();
		}
		TimeQuantum temp = timeQuantumMapper.selectByPrimaryKey(id);
		if (temp == null) {
			log.info("找不到timeQuantum信息：" + id);
			throw new DataNotFoundException(EnumTimeQuantum.DATA_NOT_FOUND);
		}
		if (!temp.getShopId().equals(staff.getShopId())) {
			throw new BusinessException(EnumTimeQuantum.NOT_FIT_SHOP);
		}
		timeQuantumMapper.deleteByPrimaryKey(id);
		log.info("删除timeQuantum成功：" + id);
		return new ResultVo();
	}

	@Override
	public TimeQuantum selectById(Long id) {
		if (id == null) {
			throw new NullPointerException();
		}
		TimeQuantum temp = timeQuantumMapper.selectByPrimaryKey(id);
		if (temp == null) {
			throw new BusinessException(EnumTimeQuantum.DATA_NOT_FOUND);
		}
		return temp;
	}

}
